//
//  SYDAmapLocation.m
//  PinGJByOwnerSide
//
//  Created by lantaiyuan on 2017/9/5.
//  Copyright © 2017年 lantaiyuan. All rights reserved.
//

#import "SYDAmapLocation.h"
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <AMapLocationKit/AMapLocationKit.h>
#import <CoreLocation/CLLocationManager.h>

@interface SYDAmapLocation ()<AMapLocationManagerDelegate, AMapSearchDelegate>
@property (nonatomic, strong) AMapLocationManager * locationManager;    // 高德
@property (nonatomic, strong) SYDCLLocationManager * cllocationManager;  // 系统
@property (nonatomic, strong) AMapSearchAPI * amapSearch;

@end


static SYDAmapLocation * _locationTool = nil;
@implementation SYDAmapLocation


+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    if (!_locationTool) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _locationTool = [super allocWithZone:zone];
        });
    }
    return _locationTool;
}

- (instancetype)init{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _locationTool = [super init];
    });
    
    [self config];
    return _locationTool;
}

+ (instancetype)shareLocationTool{
    return [[self alloc] init];
}


#pragma mark - Lazy
- (AMapLocationManager *)locationManager{
    if (!_locationManager) {
        _locationManager = [[AMapLocationManager alloc] init];
        _locationManager.delegate = self;
    }
    return _locationManager;
}

- (SYDCLLocationManager *)cllocationManager{
    if (!_cllocationManager) {
        _cllocationManager = [[SYDCLLocationManager alloc] init];
    }
    return _cllocationManager;
}

- (AMapSearchAPI *)amapSearch{
    if (!_amapSearch) {
        _amapSearch = [[AMapSearchAPI alloc] init];
        _amapSearch.delegate = self;
    }
    return _amapSearch;
}

- (void)config{
    [AMapServices sharedServices].apiKey = MAMAP_KEY;
    
    //[self.cllocationManager startLocation];
    
    __weak typeof(self) weakSelf = self;
    self.cllocationManager.locationBlock = ^(BOOL canServer){
        NSLog(@"定位失败");
        
        if (weakSelf.locationAuthorBlock) {
            weakSelf.locationAuthorBlock(weakSelf.cllocationManager, canServer);
        }
        return ;
    };
    
    self.cllocationManager.locationFialedBlock = ^{
        if (weakSelf.locationFailedBlock) {
            weakSelf.locationFailedBlock();
        }
    };
    
    self.cllocationManager.locationSuccess_block = ^(CLLocation * location){
        [weakSelf reGeoCodeWithLocation:location];
    };
}

#pragma mark - 高德

- (void)singleLocationWithcompletionBlock:(AMapLocatingCompletionBlock)completionBlock{
    
    NSLog(@"---单次定位--->");
    /**
     // 带逆地理信息的一次定位（返回坐标和地址信息）
     [self.locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
     //   定位超时时间，最低2s，此处设置为2s
     self.locationManager.locationTimeout =2;
     //   逆地理请求超时时间，最低2s，此处设置为2s
     self.locationManager.reGeocodeTimeout = 2;
     */
    
    // 带逆地理信息的一次定位（返回坐标和地址信息）
    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    //   定位超时时间，最低2s，此处设置为10s
    self.locationManager.locationTimeout =10;
    //   逆地理请求超时时间，最低2s，此处设置为10s
    self.locationManager.reGeocodeTimeout = 10;
    
    // 带逆地理（返回坐标和地址信息）。将下面代码中的 YES 改成 NO ，则不会返回地址信息。
    [self.locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
        
        completionBlock(location, regeocode,error);
    }];
}

// 单次定位
- (void)singleLocation{
    NSLog(@"---单次定位--->");
    /**
     // 带逆地理信息的一次定位（返回坐标和地址信息）
     [self.locationManager setDesiredAccuracy:kCLLocationAccuracyHundredMeters];
     //   定位超时时间，最低2s，此处设置为2s
     self.locationManager.locationTimeout =2;
     //   逆地理请求超时时间，最低2s，此处设置为2s
     self.locationManager.reGeocodeTimeout = 2;
     */
    
    // 带逆地理信息的一次定位（返回坐标和地址信息）
    [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    //   定位超时时间，最低2s，此处设置为10s
    self.locationManager.locationTimeout =10;
    //   逆地理请求超时时间，最低2s，此处设置为10s
    self.locationManager.reGeocodeTimeout = 10;
    
    // 带逆地理（返回坐标和地址信息）。将下面代码中的 YES 改成 NO ，则不会返回地址信息。
    [self.locationManager requestLocationWithReGeocode:YES completionBlock:^(CLLocation *location, AMapLocationReGeocode *regeocode, NSError *error) {
        
        if (error)
        {
            NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);
            
            if (error.code == AMapLocationErrorLocateFailed)
            {
                return;
            }
        }
        
        NSLog(@"location:%@", location);
        
        if (regeocode)
        {
            NSLog(@"reGeocode:%@", regeocode);
        }
    }];
}

// 待续定位
- (void)continueLocation{
    [self config];
    NSLog(@"---持续定位--->");
    //    self.locationManager.distanceFilter = 200;
    [self.locationManager setLocatingWithReGeocode:YES];
    [self.locationManager startUpdatingLocation];
}

- (void)stopContinueLocation{
    [self.locationManager stopUpdatingLocation];
}

- (void)reGeoCodeWithLocation:(CLLocation *)location{
    AMapReGeocodeSearchRequest *regeo = [[AMapReGeocodeSearchRequest alloc] init];
    
    regeo.location                    = [AMapGeoPoint locationWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude];
    regeo.requireExtension            = YES;
    [self.amapSearch AMapReGoecodeSearch:regeo];
}

#pragma mark - AMapLocationManagerDelegate
- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location
{
    NSLog(@"location:{lat:%f; lon:%f; accuracy:%f}", location.coordinate.latitude, location.coordinate.longitude, location.horizontalAccuracy);
}

- (void)amapLocationManager:(AMapLocationManager *)manager didUpdateLocation:(CLLocation *)location reGeocode:(AMapLocationReGeocode *)reGeocode
{
    NSLog(@"location:{lat:%f; lon:%f; accuracy:%f}", location.coordinate.latitude, location.coordinate.longitude, location.horizontalAccuracy);
    if (reGeocode)
    {
        NSLog(@"reGeocode:%@", reGeocode);
    }
}

#pragma mark - AMapSearchDelegate
- (void)onReGeocodeSearchDone:(AMapReGeocodeSearchRequest *)request response:(AMapReGeocodeSearchResponse *)response{
    if (response.regeocode) {
        NSLog(@"reGeocode:%@", response.regeocode.formattedAddress);
        if (_systemLocationSuccessBlock) {
            _systemLocationSuccessBlock(response.regeocode.addressComponent.city);
        }
    }
}

- (void)AMapSearchRequest:(id)request didFailWithError:(NSError *)error{
    if (_systemLocationSuccessBlock) {
        _systemLocationSuccessBlock(nil);
    }
}

@end
